package com.example.api.client;


import com.example.api.client.fallback.AccountFallback;
import com.example.api.client.configuration.AccountConfiguration;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cloud.openfeign.CollectionFormat;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

//@FeignClient(name = "account", url="http://service.example.com/")
//@FeignClient(name = "account", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
@FeignClient(value = "account", url = "http://127.0.0.1:18084", configuration = AccountConfiguration.class, fallback = AccountFallback.class)
public interface AccountClient {

    /**
     * 当你第一次请求该接口时，会向远程发送请求，再次访问后直接从缓存中获取数据。
     * @param id int
     * @return object
     */
    @Cacheable(cacheNames = "account", key = "#id")
    @GetMapping("/info/{id}")
    Object info(@PathVariable("id") Integer id);

    /**
     * 用于将 POJO 或 Map 参数注释为查询参数映射
     * @param params
     * @return
     */
    //@GetMapping("/format")
    //Object format(@SpringQueryMap Account params) ;

    /**
     * 如果方法参数传递的是映射，则路径段是通过用 = 连接映射中的键值对创建的。
     * 如果传递的是不同的对象，则使用 = 将提供的名称或注解的变量名称与提供的方法参数连接起来
     * 需要路径占位符的名称与@MatrixVariable注解的变量名一致。
     * @param params
     * @return
     */
    @GetMapping("/m3/{params}")
    Object matrix3(@MatrixVariable Map<String, List<String>> params);

    /**
     * 可以通过传递所需的注解值，为 Feign 客户端方法（或整个类的所有方法）添加注解
     * @param ids List.of("S1", "S2", "S3") CSV: S1,S2,S3 PIPES: S1|S2|S3
     * @return
     */
    @GetMapping("/cf")
    @CollectionFormat(feign.CollectionFormat.CSV)
    Object cf(@RequestParam("ids") List<String> ids);

    /**
     * 从用户账户中借出
     */
    @PostMapping(path = "/account")
    String debit(@RequestParam("userId") String userId, @RequestParam("money") int money);
}
